package com.atguigu.gulimail.auth.controller;

import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.exception.BizCodeEnum;
import com.atguigu.common.service.member.ProviderMemberServie;
import com.atguigu.common.utils.R;
import com.atguigu.common.vo.MemberRespVo;
import com.atguigu.common.vo.UserLogin;
import com.atguigu.gulimail.auth.feign.MemberFeignService;
import com.atguigu.gulimail.auth.feign.ThirdPartyopenFeignService;
import com.atguigu.gulimail.auth.vo.UserRegistVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author fangy
 * @date 2022-10-05 15:57
 */
@Controller
@Api(value = "登录接口",tags = "gulimail-auth-server")
public class LoginController {

    @DubboReference(check = false)
    ProviderMemberServie memberServie;

    @Autowired
    ThirdPartyopenFeignService thirdPartyopenFeignService;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    MemberFeignService memberFeignService;

    @ResponseBody
    @RequestMapping("/send/sms")
    @ApiOperation(value = "短信接口",httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "string",name = "phone",value = "用户登录账号",required = true)
    })
    public R sendSms(@RequestParam String phone){

        /**
         * 这一步主要是一分钟之内不能多次发送短信
         */
        String FromRedisCode = redisTemplate.opsForValue().get(phone);
        if(!StringUtils.isEmpty(FromRedisCode)){
            String time = FromRedisCode.split("_")[1];

            Long currentTime = System.currentTimeMillis();

            Long beforeTime = Long.parseLong(time);

            if((currentTime - beforeTime) < 60000){
                return R.error(BizCodeEnum.VAILD_SMSTIME_EXCEPTION.getCode(),BizCodeEnum.VAILD_SMSTIME_EXCEPTION.getMsg());

            }
        }

        String initcode = UUID.randomUUID().toString().substring(0, 4)+"_"+System.currentTimeMillis();

        String code = initcode.split("_")[0];
        thirdPartyopenFeignService.sendSms(phone,code);

        redisTemplate.opsForValue().set(phone,initcode,10, TimeUnit.MINUTES);


        return R.ok();
    }




    @PostMapping("/regist")
    @ApiOperation(value = "注册接口",httpMethod = "POST")
    public String regist(@Valid UserRegistVo registVo,
                         BindingResult result,
                         Model model,
                         RedirectAttributes redirectAttributes){

        if(result.hasErrors()){

            Map<String, String> collect = result.getFieldErrors().stream().collect(Collectors.toMap(
//                    (item)->{return item.getField();},
                    FieldError::getField,
//                    (e)->{return e.getDefaultMessage();}
                    FieldError::getDefaultMessage
            ));

            System.out.println(collect);
            redirectAttributes.addFlashAttribute("errors",collect);

            return "redirect:http://auth.gulimail.com/reg.html";
        }

        //经过验证后开始注册
        String code = registVo.getCode();
        String phone = registVo.getPhone();

        String redisCode = redisTemplate.opsForValue().get(phone);

        if(!StringUtils.isEmpty(redisCode)){
            if(code.equals(redisCode.split("_")[0])){


                //如果比较传来的验证码和redis中的一致，就要把redis中的删除
                redisTemplate.delete(phone);

                //比对完成后可以调用远程接口注册
                R r = memberFeignService.saveUer(registVo);

                if(r.getCode() == 0){

                    //注册成功   跳转登录页面
                    return "redirect:http://auth.gulimail.com/login.html";
                }else{

                    Map<String, String> errors = new HashMap<>();
                    errors.put("msg", (String) r.get("msg"));
                    redirectAttributes.addFlashAttribute("errors",errors);
                    return "redirect:http://auth.gulimail.com/reg.html";
                }

            }else {
                //验证码不一样  throws   验证码输入错误   跳转注册页面
                Map<String, String> errors = new HashMap<>();
                errors.put("code","验证码错误");
                redirectAttributes.addFlashAttribute("errors",errors);
                return "redirect:http://auth.gulimail.com/reg.html";
            }
        }else{
            //redisCode为空的话就  throws   过期     跳转注册页面
            Map<String, String> errors = new HashMap<>();
            errors.put("code","验证码错误");
            redirectAttributes.addFlashAttribute("errors",errors);
            return "redirect:http://auth.gulimail.com/reg.html";
        }
    }


    @PostMapping("/login")
    public String login(UserLogin userLogin,
                        HttpSession session,
                        RedirectAttributes redirectAttributes){

        System.out.println(userLogin);

        R r = memberServie.loginByUserLogin(userLogin);

        if (r.getCode() == 0){

            MemberRespVo data = r.getData(new TypeReference<MemberRespVo>() {
            });

            session.setAttribute("loginUser",data);
            return "redirect:http://gulimail.com";
        }else{

            Map<String, String> errors = new HashMap<>();
            errors.put("msg", (String) r.get("msg"));
            redirectAttributes.addFlashAttribute("errors",errors);
            return "redirect:http://auth.gulimail.com/login.html";


        }

    }

}
